package com.train.course.controller;

import com.train.common.annotation.Anonymous;
import com.train.common.core.domain.AjaxResult;
import com.train.common.service.MinioService;
import com.train.course.domain.VideoAction;
import com.train.course.domain.VideoCourse;
import com.train.course.domain.VideoEpisode;
import com.train.course.service.IVideoActionService;
import com.train.course.service.IVideoCourseService;
import com.train.course.service.IVideoEpisodeService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;

/**
 * 视频上传控制器
 */
@RestController
@RequestMapping("/admin/video")
public class VideoUploadController {

    @Autowired
    private MinioService minioService;

    @Autowired
    private IVideoEpisodeService videoEpisodeService;

    @Autowired
    private IVideoCourseService videoCourseService;

    @Autowired
    private IVideoActionService videoActionService;

    /**
     * 获取视频上传凭证（前端直传模式）
     * @param originalFilename 原始文件名
     * @param fileType 文件类型（video/cover）
     * @param fileCategory 文件分类（course/action）
     * @param courseId 课程ID（可选）
     * @param episodeId 视频集ID（可选）
     * @param actionId 分解动作ID（可选）
     * @return 上传凭证信息
     */
    @Anonymous
    @GetMapping("/upload-credentials")
    public AjaxResult getUploadCredentials(@RequestParam String originalFilename,
                                           @RequestParam String fileType,
                                           @RequestParam String fileCategory,
                                           @RequestParam(required = false) Long courseId,
                                           @RequestParam(required = false) Long episodeId,
                                           @RequestParam(required = false) Long actionId) {
        // 根据文件类型和分类设置不同的前缀
        StringBuilder prefixBuilder = new StringBuilder(fileCategory + "/" + (fileType.equals("video") ? "videos/" : "covers/") + "/");

        // 添加课程ID
        if (courseId != null) {
            prefixBuilder.append(courseId).append("/");
            // 添加视频集ID
            if (episodeId != null) {
                prefixBuilder.append(episodeId).append("/");
                // 添加分解动作ID
                if (actionId != null) {
                    prefixBuilder.append(actionId).append("/");
                }
            }
        }

        String prefix = prefixBuilder.toString();
        Map<String, String> credentials = minioService.getUploadCredentials(originalFilename, prefix);

        // 在返回结果中添加相关ID信息
        Map<String, Object> result = new HashMap<>(credentials);
        if (courseId != null) result.put("courseId", courseId);
        if (episodeId != null) result.put("episodeId", episodeId);
        if (actionId != null) result.put("actionId", actionId);

        return AjaxResult.success(result);
    }

    /**
     * 上传课程视频（后端中转模式）
     * @param file 视频文件
     * @param courseId 课程ID
     * @param episodeId 视频集ID（必选，用于自动更新视频集URL）
     * @return 上传结果
     */
    @Anonymous
    @PostMapping("/upload-course-video")
    public AjaxResult uploadCourseVideo(@RequestParam MultipartFile file,
                                        @RequestParam Long courseId,
                                        @RequestParam Long episodeId) {
        if (file.isEmpty()) {
            return AjaxResult.error("上传文件不能为空");
        }

        // 检查文件大小
        long maxSize = 1024 * 1024 * 1024; // 1GB
        if (file.getSize() > maxSize) {
            return AjaxResult.error("文件大小不能超过1GB");
        }

        // 根据课程ID和视频集ID创建更有组织的路径
        String pathPrefix = "course/videos/" + courseId + "/" + episodeId + "/";

        // 上传文件
        String objectName = minioService.uploadFile(file, pathPrefix);

        // 直接使用objectName存储到数据库（将由AOP自动转换为临时URL）
        VideoEpisode videoEpisode = new VideoEpisode();
        videoEpisode.setEpisodeId(episodeId);
        videoEpisode.setVideoUrl(objectName);
        int updateResult = videoEpisodeService.updateVideoEpisode(videoEpisode);

        if (updateResult <= 0) {
            // 更新失败，删除已上传的文件
            minioService.deleteFile(objectName);
            return AjaxResult.error("视频上传成功，但更新视频集信息失败");
        }

        Map<String, Object> result = new HashMap<>();
        result.put("objectName", objectName);
        result.put("courseId", courseId);
        result.put("episodeId", episodeId);
        result.put("updateStatus", "success");

        return AjaxResult.success("视频上传成功并已更新视频集信息", result);
    }

    /**
     * 上传课程封面（后端中转模式）
     * @param file 封面图片
     * @param courseId 课程ID
     * @return 上传结果
     */
    @Anonymous
    @PostMapping("/upload-course-cover")
    public AjaxResult uploadCourseCover(@RequestParam MultipartFile file, @RequestParam Long courseId) {
        if (file.isEmpty()) {
            return AjaxResult.error("上传文件不能为空");
        }

        // 检查文件大小
        long maxSize = 10 * 1024 * 1024; // 10MB
        if (file.getSize() > maxSize) {
            return AjaxResult.error("文件大小不能超过10MB");
        }

        // 上传文件到课程封面目录，包含课程ID
        String pathPrefix = "course/covers/" + courseId + "/";
        String objectName = minioService.uploadFile(file, pathPrefix);

        // 直接使用objectName存储到数据库（将由AOP自动转换为临时URL）
        VideoCourse videoCourse = new VideoCourse();
        videoCourse.setCourseId(courseId);
        videoCourse.setCoverUrl(objectName);
        int updateResult = videoCourseService.updateVideoCourse(videoCourse);

        if (updateResult <= 0) {
            // 更新失败，删除已上传的文件
            minioService.deleteFile(objectName);
            return AjaxResult.error("封面上传成功，但更新课程封面信息失败");
        }

        Map<String, Object> result = new HashMap<>();
        result.put("objectName", objectName);
        result.put("courseId", courseId);
        result.put("updateStatus", "success");

        return AjaxResult.success("封面上传成功并已更新课程信息", result);
    }

    /**
     * 上传视频集封面（后端中转模式）
     * @param file 封面图片
     * @param courseId 课程ID
     * @param episodeId 视频集ID
     * @return 上传结果
     */
    @Anonymous
    @PostMapping("/upload-episode-cover")
    public AjaxResult uploadEpisodeCover(@RequestParam MultipartFile file,
                                         @RequestParam Long courseId,
                                         @RequestParam Long episodeId) {
        if (file.isEmpty()) {
            return AjaxResult.error("上传文件不能为空");
        }

        // 检查文件大小
        long maxSize = 5 * 1024 * 1024; // 5MB
        if (file.getSize() > maxSize) {
            return AjaxResult.error("文件大小不能超过5MB");
        }

        // 上传文件到视频集封面目录，包含课程ID和视频集ID
        String pathPrefix = "episode/covers/" + courseId + "/" + episodeId + "/";
        String objectName = minioService.uploadFile(file, pathPrefix);

        // 直接使用objectName存储到数据库（将由AOP自动转换为临时URL）
        VideoEpisode videoEpisode = new VideoEpisode();
        videoEpisode.setEpisodeId(episodeId);
        videoEpisode.setCoverUrl(objectName);
        int updateResult = videoEpisodeService.updateVideoEpisode(videoEpisode);

        if (updateResult <= 0) {
            // 更新失败，删除已上传的文件
            minioService.deleteFile(objectName);
            return AjaxResult.error("封面上传成功，但更新视频集封面信息失败");
        }

        Map<String, Object> result = new HashMap<>();
        result.put("objectName", objectName);
        result.put("coverUrl", objectName);
        result.put("courseId", courseId);
        result.put("episodeId", episodeId);
        result.put("updateStatus", "success");

        return AjaxResult.success("封面上传成功并已更新视频集信息", result);
    }

    /**
     * 上传分解动作视频（后端中转模式）
     * @param file 视频文件
     * @param courseId 课程ID
     * @param episodeId 视频集ID
     * @param actionId 分解动作ID（可选）
     * @return 上传结果
     */
    @Anonymous
    @PostMapping("/upload-action-video")
    public AjaxResult uploadActionVideo(@RequestParam MultipartFile file,
                                        @RequestParam Long courseId,
                                        @RequestParam Long episodeId,
                                        @RequestParam(required = false) Long actionId) {
        if (file.isEmpty()) {
            return AjaxResult.error("上传文件不能为空");
        }

        // 检查文件大小
        long maxSize = 512 * 1024 * 1024; // 512MB
        if (file.getSize() > maxSize) {
            return AjaxResult.error("文件大小不能超过512MB");
        }

        // 上传文件到动作视频目录，包含课程ID和视频集ID
        String pathPrefix = "action/videos/" + courseId + "/" + episodeId + "/";
        if (actionId != null) {
            pathPrefix += actionId + "/";
        }
        String objectName = minioService.uploadFile(file, pathPrefix);

        // 如果提供了actionId，则自动更新分解动作的videoUrl
        if (actionId != null) {
            VideoAction videoAction = new VideoAction();
            videoAction.setActionId(actionId);
            videoAction.setVideoUrl(objectName);
            int updateResult = videoActionService.updateVideoAction(videoAction);

            if (updateResult <= 0) {
                // 更新失败，删除已上传的文件
                minioService.deleteFile(objectName);
                return AjaxResult.error("视频上传成功，但更新分解动作信息失败");
            }
        }

        Map<String, Object> result = new HashMap<>();
        result.put("objectName", objectName);
        result.put("courseId", courseId);
        result.put("episodeId", episodeId);
        if (actionId != null) {
            result.put("actionId", actionId);
            result.put("updateStatus", "success");
        }

        return AjaxResult.success(actionId != null ? "视频上传成功并已更新分解动作信息" : "视频上传成功", result);
    }

    /**
     * 上传分解动作封面（后端中转模式）
     * @param file 封面图片
     * @param courseId 课程ID
     * @param episodeId 视频集ID
     * @param actionId 分解动作ID（可选）
     * @return 上传结果
     */
    @Anonymous
    @PostMapping("/upload-action-cover")
    public AjaxResult uploadActionCover(@RequestParam MultipartFile file,
                                        @RequestParam Long courseId,
                                        @RequestParam Long episodeId,
                                        @RequestParam(required = false) Long actionId) {
        if (file.isEmpty()) {
            return AjaxResult.error("上传文件不能为空");
        }

        // 检查文件大小
        long maxSize = 5 * 1024 * 1024; // 5MB
        if (file.getSize() > maxSize) {
            return AjaxResult.error("文件大小不能超过5MB");
        }

        // 上传文件到动作封面目录，包含课程ID和视频集ID
        String pathPrefix = "action/covers/" + courseId + "/" + episodeId + "/";
        if (actionId != null) {
            pathPrefix += actionId + "/";
        }
        String objectName = minioService.uploadFile(file, pathPrefix);

        // 如果提供了actionId，则自动更新分解动作的coverUrl
        if (actionId != null) {
            VideoAction videoAction = new VideoAction();
            videoAction.setActionId(actionId);
            videoAction.setCoverUrl(objectName);
            int updateResult = videoActionService.updateVideoAction(videoAction);

            if (updateResult <= 0) {
                // 更新失败，删除已上传的文件
                minioService.deleteFile(objectName);
                return AjaxResult.error("封面上传成功，但更新分解动作信息失败");
            }
        }

        Map<String, Object> result = new HashMap<>();
        result.put("objectName", objectName);
        result.put("courseId", courseId);
        result.put("episodeId", episodeId);
        if (actionId != null) {
            result.put("actionId", actionId);
            result.put("updateStatus", "success");
        }

        return AjaxResult.success(actionId != null ? "封面上传成功并已更新分解动作信息" : "封面上传成功", result);
    }

    /**
     * 删除文件
     * @param objectName 文件对象名
     * @return 删除结果
     */
    @Anonymous
    @DeleteMapping("/delete")
    public AjaxResult deleteFile(@RequestParam String objectName) {
        minioService.deleteFile(objectName);
        return AjaxResult.success("文件删除成功");
    }
}


